#ifndef __USB_IN_STREAM_H__
#define __USB_IN_STREAM_H__

#include <queue>
#include <memory>
#include <map>
#include <mutex>
#include <string>
#include <functional>
#include "Pal/VideoDec.h"
#include "Poller/Timer.h"
#include "json.h"
// #include "Config.h"
#include "Thread/Thread.h"
#include "StreamComposeMgr.h"
#include "Pal/AudioIn.h"
#include "mediaPriv.h"



namespace Media{

class VideoDecode;
class AudioInMgr;
class UsbAVStream;

#define H265_TYPE(v) (((uint8_t)(v) >> 1) & 0x3f)

#define H264_TYPE(v) ((uint8_t)(v) & 0x1F)


class UsbInStream{
public:

    //视频数据集
    struct FrameBuffer 
	{
	    uint64_t timestamp; /*< timestamp*/
		size_t size; /*< data length*/
		uint8_t* data; /*< raw data*/

		FrameBuffer(size_t len)
		: timestamp(0)
		, size(len)
		, data(NULL)
		{
			data = new uint8_t[len];
		}

		~FrameBuffer()
		{
			delete []data;
			data = NULL;
		}

		FrameBuffer(const FrameBuffer&);
		FrameBuffer& operator=(const FrameBuffer&);
	};

    // 定义智能指针
    typedef std::shared_ptr<FrameBuffer> FramePtr;

    
public:

	static UsbInStream *instance(std::string channel);

	bool stop(bool flag); 

	bool start(StreamPlayInfo playInfo);

	bool onVideoFrame(void *buffer, int length);

	bool onAudioFrame(void *buffer, int length);

	bool outputStart(StreamOutInterface type, std::string usbPort);

	bool outputStop(StreamOutInterface type, std::string usbPort, bool flag);

	bool getOutputInfo(StreamOutInterface type, std::string usbPort, int *sampleRate, int *channels);

	bool directGetVideoData(SCREEN_vencPacket_t * packet);

	bool usbStatusCallback(std::string usbport, bool status);

	bool clearVideoQueue(uint8_t index);

	bool volumeFactorSet(int value);

	bool getUsbDevAbility(int& ability);

	bool isH26xFormat();

	bool dynamicStartVideo(bool actFlg);

private:
	UsbInStream(std::string channel);

	bool streamStart();
	
	bool streamStop(void);

	bool sendVideoPacket(unsigned char *buffer, int buflen, uint64_t timestamp);

    bool sendAudioPacket(unsigned char *buffer, int buflen, uint64_t timestamp);

    void ThreadProc(Fdt::Thread *thread);

	bool SaveToCommQueue(FramePtr& msg, uint8_t index);

	bool GetCommQueueMsg(FramePtr& msg, uint8_t index);

    void StreamInProc(Fdt::Thread *thread);

    bool audioVolumeConvert(short* audioData, int dataLen);

    bool getUsbAudioParams(std::string usbPort, int ability, Json::Value &outParams);

private:
	static std::map<std::string, UsbInStream *> sm_streamMap;

	static std::recursive_mutex 			sm_mapMutex;

	const uint16_t                          QueueSize = 10;

	static const uint8_t                    QueueArray = 2;

    VideoDecode *                           m_pVideoDecode = nullptr;
	
	int 									m_videoChannel = -1;
	
	bool									m_started = false; //start作为启动标志,避免多个业务多次启停

	VideoDecPacket                          m_videoPacket;

	std::shared_ptr<Fdt::Timer>             m_taskTimer;

	TaskInfo                                m_taskInfo = {0};

	StreamAbility                           m_playAbility = VIDEO_AUDIO;

    int 									m_audioChannel = -1;

	AudioInPacket                           m_audioPacket; 

	AudioInMgr *                            m_pAudioInput = nullptr;

    UsbAVStream *                           m_usbStreamCtl = nullptr;

	int                                     m_usbInAbility = 0;

	std::string                             m_usbName = "usb-1.1";

	bool                                    m_outEnable = false;

	std::string                             m_usbOutPort;

	StreamOutInterface                      m_outType;

	int                                     m_outRates = 0;

	std::mutex                              m_queueMutex[QueueArray];

	std::queue<FramePtr>                    m_frameaQueue[QueueArray];

    FramePtr                                m_framePtr;

    StreamInfo                              m_streamInfo;

    bool                                    m_playFlg = false;

    StreamPlayInfo                          m_curPlayInfo;

    bool                                    m_dropFrame = true;

    std::string                             m_usbInFormat = "";

    uint8_t                                 m_volumeFactor = 100;

    Json::Value                             m_uacOutParams = Json::nullValue;

    std::atomic<bool>                       m_dynamicStartVideo = false;

    Fdt::Thread 						    m_streamInThread{"UsbInStream"};//thread放在最后,保证thread最后构造,最先析构
	
	Fdt::Thread 						    m_thread{"UsbOutStream"};//thread放在最后,保证thread最后构造,最先析构

};

}//namespace Media
#endif

